package com.traffic.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import com.traffic.annotation.Power;
import com.traffic.constant.Const;
import com.traffic.constant.Status;
import com.traffic.entity.*;
import com.traffic.exception.BaseException;
import com.traffic.mapper.AdminMapper;
import com.traffic.mapper.AuthMapper;
import com.traffic.mapper.RoleMapper;
import com.traffic.mapper.UserMapper;
import com.traffic.service.AuthService;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Created by IntelliJ IDEA.
 * User: KingRainGrey
 * Date: 2020/9/27
 */
@Service
@Slf4j
public class AuthServiceImpl extends ServiceImpl<AuthMapper, Auth> implements AuthService {
    @Autowired
    private AuthMapper authMapper;
    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private UserMapper userMapper;


    /**
     * 获取权限列表
     * @return
     */
    @Override
    public List<Auth> getAuthList() {
        QueryWrapper<Auth> wrapper = new QueryWrapper<>();
        return authMapper.selectList(wrapper);
    }

    /**
     * 最高权限管理员编辑角色权限-添加
     * @param authId
     * @param roleId
     * @return
     */
    @Transactional
    @Power(authority = Const.AUTH_ADMIN)
    @Override
    public Boolean giveAuth(Long authId, Long roleId) {
        log.debug("【开始权限模块】");
        Role role = roleMapper.selectById(roleId);
        log.debug("【申请角色】:{}",role.getName());
        if (ObjectUtil.isNotNull(role)) {
            List<String> authList = new ArrayList<>();
            if (ObjectUtil.isNotNull(role.getAuthority())) {
                authStringToList(role, authList);
            }
            Auth auth = authMapper.selectById(authId);
            if (ObjectUtil.isNotNull(auth)) {
                log.debug("【申请权限】:{}", auth.getAuth());
                String newAuth = auth.getAuth().trim();
                // 重复申请权限处理
                if (!authList.contains(newAuth)) {
                    authList.add(newAuth);
                }
                log.debug("【所有权限】:{}", authList);
                String allAuth = Joiner.on("-").join(authList);
                role.setAuthority(allAuth);
                roleMapper.updateById(role);
                return true;
            }else {
                throw new BaseException(Status.AUTH_NO_ERROR);
            }
        }else {
            throw new BaseException(Status.ROLE_NO_ERROR);
        }
    }

    /**
     * 最高权限管理员编辑角色的权限-移除
     * @param authId
     * @param
     * @return
     */
    @Transactional
    @Power(authority = Const.AUTH_ADMIN)
    @Override
    public Boolean removeAuth(Long authId, Long roleId) {
        Role role = roleMapper.selectById(roleId);
        if (ObjectUtil.isNotNull(role)) {
            List<String> authList = new ArrayList<>();
            authStringToList(role, authList);
            log.info("【当前拥有权限】:{}", authList);
            Auth auth = authMapper.selectById(authId);
            log.info("【移除权限】:{}", auth.getAuth());
            if (ObjectUtil.isNotNull(auth)) {
                if (authList.contains(auth.getAuth())) {
                    List<String> newAuthList = new ArrayList<>();
                    authList.forEach(temp->{
                        if (!StrUtil.equals(auth.getAuth(), temp)) {
                            newAuthList.add(temp);
                        }
                    });
                    log.info("{}", newAuthList);
                    String newAuth = "";
                    if (newAuthList.size() > 1) {
                        newAuth = Joiner.on("-").join(newAuthList);
                    }else if (newAuthList.size() == 1) {
                        newAuth = newAuthList.get(0);
                    }
                    role.setAuthority(newAuth);
                    roleMapper.updateById(role);
                    return true;
                } else {
                    throw new BaseException(Status.ACCOUNT_NO_THIS_AUTH);
                }
            }else {
                throw new BaseException(Status.AUTH_NO_ERROR);
            }
        }else {
            throw new BaseException(Status.ROLE_NO_ERROR);
        }
    }


    /**
     * 新增一个角色
     * @param name
     * @return
     */
    @Override
    @Power(authority = Const.AUTH_ADMIN)
    public Role addRole(String name) {
        Role role = Role.builder().name(name).build();
        roleMapper.insert(role);
        return role;
    }

    /**
     * 修改一个角色的名称
     * @param name
     * @param roleId
     * @return
     */
    @Override
    @Power(authority = Const.AUTH_ADMIN)
    public Role editRole(String name, Long roleId) {
        Role role = roleMapper.selectById(roleId);
        role.setName(name);
        roleMapper.updateById(role);
        return role;
    }

    /**
     * 根据角色名字查询角色
     * @param name
     * @return
     */
    @Override
    public Role findRole(String name) {
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper.eq("name", name);
        Role role = roleMapper.selectOne(wrapper);
        return role;
    }

    /**
     * 根据条件筛选角色
     * 分页
     * @param currentPage 当前页码
     * @param pageSize 每页记录条数
     * @return
     */
    @Override
    public List<Role> queryRoles(Integer currentPage, Integer pageSize) {
        IPage<Role> rolePage = new Page<>(currentPage, pageSize);
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        // add where
        wrapper.orderByDesc("id");
        IPage<Role> page = roleMapper.selectPage(rolePage, wrapper);
        return page.getRecords();
    }

    /**
     * 分页查询角色
     * @param currentPage
     * @param pageSize
     * @return
     */
    @Override
    public QueryResult queryRolesPages(Integer currentPage, Integer pageSize) {
        IPage<Role> rolePage = new Page<>(currentPage, pageSize);
        QueryWrapper<Role> wrapper = new QueryWrapper<>();

        wrapper.orderByAsc("id");
        IPage<Role> page = roleMapper.selectPage(rolePage, wrapper);
        Integer total = roleMapper.selectCount(wrapper);
        QueryResult result = QueryResult.builder().data(page.getRecords()).total(total).build();
        return result;
    }

    /**
     * 管理员账户设置角色
     * @param adminId
     * @param roleId
     * @return
     */
    @Override
    @Transactional
    @Power(authority = Const.AUTH_ADMIN)
    public Boolean setRoleAdmin(Long adminId, Long roleId) {
        Admin admin = adminMapper.selectById(adminId);
        if (ObjectUtil.isNotNull(admin)) {
            Role role = roleMapper.selectById(roleId);
            if (ObjectUtil.isNotNull(role)) {
                admin.setRole(roleId);
                adminMapper.updateById(admin);
                return Boolean.TRUE;
            }
        }
        return false;
    }

    /**
     * 用户账户设置角色
     * @param userId
     * @param roleId
     * @return
     */
    @Override
    @Transactional
    @Power(authority = Const.AUTH_ADMIN)
    public Boolean setRoleUser(Long userId, Long roleId) {
        User user = userMapper.selectById(userId);
        Role role = roleMapper.selectById(roleId);
        if (ObjectUtil.isNotNull(user) && ObjectUtil.isNotNull(role)) {
            user.setRole(roleId);
            userMapper.updateById(user);
            return true;
        }
        return false;
    }

    private void authStringToList(Role role, List<String> authList) {
        if (role.getAuthority().contains(Const.STRING_SPLIT)) {
            List<String> tempAuthList = Arrays.asList(role.getAuthority().trim().split(Const.STRING_SPLIT));
            tempAuthList.forEach(temp->{
                authList.add(temp);
            });
        }else {
            authList.add(role.getAuthority());
        }
    }

    /**
     * 删除权限
     * @param id
     * @return
     */
    @Power(authority = Const.AUTH_ADMIN)
    @Override
    public Boolean deleteRole(Long id) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("role", id);
        int total = userMapper.selectCount(wrapper);
        if(total > 0) {
            return false;
        }
        int result = roleMapper.deleteById(id);
        if (result > 0) {
            return true;
        }
        return false;
    }

    /**
     * 角色批量删除
     * @param ids
     * @return
     */
    @Power(authority = Const.AUTH_ADMIN)
    @Override
    public Integer deleteRole(List<Long> ids) {
        AtomicReference<Integer> wrong = new AtomicReference<>(0);
        ids.forEach(id->{
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.eq("role", id);
            int total = userMapper.selectCount(wrapper);
            if(total > 0) {
                wrong.getAndSet(wrong.get() + 1);
            }else {
                int result = roleMapper.deleteById(id);
                if (result <= 0) {
                    wrong.getAndSet(wrong.get() + 1);
                }
            }
        });
        return wrong.get();
    }

    /**
     * 获取所有设置的角色
     * @return
     */
    @Override
    public List<Role> getAllRole() {
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("id");
        return roleMapper.selectList(wrapper);
    }

    /**
     * 获取所有的auth
     * @return
     */
    @Override
    public List<Auth> getAllAuth() {
        QueryWrapper<Auth> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("id");
        return authMapper.selectList(wrapper);
    }

    /**
     * 添加一个role
     * @param name
     * @param auths
     * @return
     */
    @Override
    @Power(authority = Const.AUTH_ADMIN)
    public Boolean createRole(String name, List<Integer> auths) {
        List<String> authority = new ArrayList<>();
        List<String> authName = new ArrayList<>();
        List<Long> authId = new ArrayList<>();
        auths.forEach(auth -> {
            Auth a = authMapper.selectById(auth);
            if (ObjectUtil.isNotNull(a)) {
                authority.add(a.getAuth());
                authName.add(a.getName());
                authId.add(a.getId());
            }
        });

        Role role = Role.builder().name(name)
                .authority(StrUtil.join("-", authority))
                .authName(StrUtil.join("、", authName))
                .array(StrUtil.join("-", authId))
                .build();
        int result = roleMapper.insert(role);
        if (result > 0) {
            return true;
        }
        return false;
    }

    /**
     * 修改role信息
     * @param id
     * @param name
     * @param auths
     * @return
     */
    @Power(authority = Const.AUTH_ADMIN)
    @Override
    public Boolean editRole(Integer id, String name, List<Integer> auths) {
        Role role = roleMapper.selectById(id);
        if (ObjectUtil.isNotNull(role)) {
            List<String> authority = new ArrayList<>();
            List<String> authName = new ArrayList<>();
            List<Long> authId = new ArrayList<>();
            auths.forEach(auth -> {
                Auth a = authMapper.selectById(auth);
                if (ObjectUtil.isNotNull(a)) {
                    authority.add(a.getAuth());
                    authName.add(a.getName());
                    authId.add(a.getId());
                }
            });

            role.setName(name);
            role.setAuthority(StrUtil.join("-", authority));
            role.setAuthName(StrUtil.join("、", authName));
            role.setArray(StrUtil.join("-", authId));
            int result = roleMapper.updateById(role);
            if (result > 0) {
                return true;
            }
            return false;
        }
        return false;
    }

    /**
     * 通过id查询role
     * @param id
     * @return
     */
    @Override
    public Role queryRoleById(Integer id) {
        Role role = roleMapper.selectById(id);
        if (ObjectUtil.isNotNull(role)) {
            String [] list = role.getArray().split("-");
            List<Long> arr = new ArrayList<>();
            for (int i=0;i<list.length;i++) {
                arr.add(Long.parseLong(list[i]));
            }
            role.setAuth(arr);
        }
        return role;
    }
}
